﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Web;
//using System.Web.Script.Serialization;
//using System.Runtime.Serialization;
using Tzx.Utilities;

namespace Tzx.Tools.Payroll2Images.Exe.Api
{
    /// <summary>
    /// Web网络接口访问基础方法
    /// </summary>
    public class API_HttpHelp
    {

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain,
            SslPolicyErrors errors)
        {
            //直接确认，否则打不开   
            return true;
        }

        #region get

        /// <summary>
        /// Get
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="addHeaders"></param>
        /// <param name="okText"></param>
        /// <param name="errorText"></param>
        /// <returns></returns>
        public static bool GetHttps(string requestUrl, Dictionary<string, string> addHeaders, out string okText,out string errorText)
        {
            okText = null;
            errorText = null;
            try
            {
                ServicePointManager.ServerCertificateValidationCallback =
                    new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                HttpWebRequest request = (HttpWebRequest) WebRequest.CreateDefault(new Uri(requestUrl));
                request.Method = "GET";

                //Headers
                if (addHeaders != null)
                {
                    foreach (KeyValuePair<string, string> kv in addHeaders)
                    {
                        request.Headers.Add(kv.Key, kv.Value);
                    }
                }

                HttpWebResponse res = (HttpWebResponse) request.GetResponse();
                Stream stream = res.GetResponseStream();
                StreamReader streamReader = new StreamReader(stream);
                okText = streamReader.ReadToEnd();
                return true;
            }
            catch (System.Net.WebException exWeb)
            {
                errorText = exWeb.Message + "[" + requestUrl + "]";
                return false;
            }
            catch (Exception ex)
            {
                errorText = "[" + ex.GetType() + "]" + ex.Message;
                return false;
            }

            //正常使用了，和访问普通的 http:// 地址一样了

        }

        #endregion

        #region post

        /// <summary>
        /// Post
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="requestParam">请求json字符串</param>
        /// <param name="method"></param>
        /// <param name="okText">out:返回字符串</param>
        /// <param name="errorText">out:返回错误</param>
        /// <returns></returns>
        public static bool PostFunction(string requestUrl, string requestParam, string method, out string okText,
            out string errorText)
        {
            return PostFunction(requestUrl, requestParam, null, method, out okText, out errorText);
        }

        /// <summary>
        /// Post
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="requestParam">请求json字符串</param>
        /// <param name="addHeaders">请求头</param>
        /// <param name="method"></param>
        /// <param name="okText">out:返回字符串</param>
        /// <param name="errorText">out:返回错误</param>
        /// <returns></returns>
        public static bool PostFunction(string requestUrl, string requestParam, Dictionary<string, string> addHeaders,
            string method, out string okText, out string errorText)
        {
            okText = null;
            errorText = null;
            try
            {
                ServicePointManager.ServerCertificateValidationCallback =
                    new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestUrl);
                request.Method = method;

                //Headers
                if (addHeaders != null)
                {
                    foreach (KeyValuePair<string, string> kv in addHeaders)
                    {
                        request.Headers.Add(kv.Key, kv.Value);
                    }
                }

                request.ContentType = "application/json";
                string strContent = requestParam;
                using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
                {
                    dataStream.Write(strContent);
                    dataStream.Close();
                }
                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                string encoding = response.ContentEncoding;
                if (string.IsNullOrEmpty(encoding))
                {
                    encoding = "UTF-8"; //默认编码  
                }
                StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
                //string retString = reader.ReadToEnd();
                //return retString;
                okText = reader.ReadToEnd();
                return true;
            }
            catch (System.Net.WebException exWeb)
            {
                errorText = exWeb.Message + "[" + requestUrl + "]";
                return false;
            }
            catch (Exception ex)
            {
                errorText = "[" + ex.GetType() +"]"+ ex.Message;
                return false;
            }
        }

        #endregion

        #region upload

        //Content-Disposition: form-data; name="media"; filename="27f9c75891b25496c807698beb3acb6f_800x0.jpg"
        //Content-Type: application/octet-stream

        /// <summary>
        /// upload
        /// </summary>
        /// <param name="requestUrl"></param>
        /// <param name="addHeaders"></param>
        /// <param name="data"></param>
        /// <param name="files"></param>
        /// <param name="okText">返回消息</param>
        /// <param name="errText">返回出错消息</param>
        /// <returns></returns>
        public static bool UploadMedia(string requestUrl, Dictionary<string, string> addHeaders, NameValueCollection data, string[] files, out string okText,out string errText)
        {
            okText = null;
            errText = null;

            try
            {
                ServicePointManager.ServerCertificateValidationCallback =
                    new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                //HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);

                Encoding encoding = Encoding.UTF8; //默认编码  

                string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
                byte[] boundarybytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
                byte[] endbytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

                //1.HttpWebRequest
                HttpWebRequest request = (HttpWebRequest) WebRequest.Create(requestUrl);

                request.ContentType = "multipart/form-data; boundary=" + boundary; //TZX:ContentType没错!2021-10-06
                //request.ContentType = "application/octet-stream";

                request.Method = "POST";
                request.KeepAlive = true;
                request.Credentials = CredentialCache.DefaultCredentials;

                //Headers
                if (addHeaders != null)
                {
                    foreach (KeyValuePair<string, string> kv in addHeaders)
                    {
                        request.Headers.Add(kv.Key, kv.Value);
                    }
                }

                using (Stream stream = request.GetRequestStream())
                {
                    //1.1 key/value
                    if (data != null)
                    {
                        foreach (string key in data.Keys)
                        {
                            stream.Write(boundarybytes, 0, boundarybytes.Length);
                            string formitem = string.Format("Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}",
                                key, data[key]);
                            byte[] formitembytes = encoding.GetBytes(formitem);
                            stream.Write(formitembytes, 0, formitembytes.Length);
                        }
                    }

                    //1.2 file
                    byte[] buffer = new byte[4096];
                    int bytesRead = 0;
                    for (int i = 0; i < files.Length; i++)
                    {
                        stream.Write(boundarybytes, 0, boundarybytes.Length);
                        string header = string.Format(
                            "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n",
                            "media",
                            Path.GetFileName(files[i])
                            ); //media,"file" + i
                        byte[] headerbytes = encoding.GetBytes(header);
                        stream.Write(headerbytes, 0, headerbytes.Length);
                        using (FileStream fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
                        {
                            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                            {
                                stream.Write(buffer, 0, bytesRead);
                            }
                        }
                    }

                    //1.3 form end
                    stream.Write(endbytes, 0, endbytes.Length);
                }

                //2.WebResponse
                HttpWebResponse response = (HttpWebResponse) request.GetResponse();
                using (StreamReader stream = new StreamReader(response.GetResponseStream()))
                {
                    okText = stream.ReadToEnd();
                    return true;
                }
            }
            catch (WebException webEx)
            {
                errText = webEx.Message + "[" + requestUrl + "]";
                return false;
            }
            catch (Exception ex)
            {
                errText = ex.Message;
                return false;
            }
        }

        #endregion

    }

}